package com.inspector.app.di.location;


import android.app.Notification;
import android.content.Context;
import android.location.Location;
import android.os.Looper;

import androidx.annotation.Nullable;

import com.huawei.hmf.tasks.OnFailureListener;
import com.huawei.hmf.tasks.OnSuccessListener;
import com.huawei.hmf.tasks.Task;
import com.huawei.hms.location.FusedLocationProviderClient;
import com.huawei.hms.location.LocationAvailability;
import com.huawei.hms.location.LocationCallback;
import com.huawei.hms.location.LocationRequest;
import com.huawei.hms.location.LocationResult;
import com.huawei.hms.location.LocationServices;
import com.huawei.hms.location.LocationSettingsRequest;
import com.huawei.hms.location.LocationSettingsResponse;
import com.huawei.hms.location.SettingsClient;
import com.inspector.app.util.LogUtil;

import java.util.List;

/**
 * @author CodeK 2023/7/3
 * <p>
 * 华为定位
 * 将UpLoadDataService中的定位抽出来
 */
public class HWLocationInstance {

    private static String TAG = "HWLocationInstance";
    private HMSLocationCallback hmsLocationCallback;
    private CustomLocationListener locationListener;
    private FusedLocationProviderClient mFusedLocationProviderClient;

    public void startLocation(Context context, @Nullable Notification notification, long minTime, CustomLocationListener locationListener) {
        this.locationListener = locationListener;
        hmsLocationCallback = new HMSLocationCallback();
        LogUtil.i(TAG, "华为定位服务 startLocation minTime:" + minTime);
        try {
            //https://developer.huawei.com/consumer/cn/doc/HMSCore-Guides/android-introduction-0000001121930588
            mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context);
            SettingsClient mSettingsClient = LocationServices.getSettingsClient(context);
            LocationRequest mLocationRequest = new LocationRequest();
            // 设置位置回调的时间间隔为6000ms，默认是5000ms。
            mLocationRequest.setInterval(minTime);
            // 设置定位类型，PRIORITY_HIGH_ACCURACY为融合定位模式。
            mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            mLocationRequest.setCoordinateType(LocationRequest.COORDINATE_TYPE_WGS84);

            // 设置回调次数为100，默认值为Integer.MAX_VALUE；。
            // 特殊情况：单次定位场景，只需设置回调次数为1，仅会发起一次定位，定位结束之后，也不需要移除定位请求。
            /*mLocationRequest.setNumUpdates(100);*/

            LocationSettingsRequest locationSettingsRequest = new LocationSettingsRequest.Builder()
                    .addLocationRequest(mLocationRequest)
                    .build();
            // Before requesting location update, invoke checkLocationSettings to check device settings. 检查设备定位开关状态
            Task<LocationSettingsResponse> locationSettingsResponseTask =
                    mSettingsClient.checkLocationSettings(locationSettingsRequest);
            locationSettingsResponseTask.addOnSuccessListener(locationSettingsResponse -> {
                LogUtil.i(TAG, "check location settings success");
                //调用requestLocationUpdates()进行定位
                mFusedLocationProviderClient.removeLocationUpdates(hmsLocationCallback);
                mFusedLocationProviderClient
                        .requestLocationUpdates(mLocationRequest, hmsLocationCallback, Looper.getMainLooper())
                        .addOnSuccessListener(aVoid -> {
                            LogUtil.i(TAG, "requestLocationUpdatesWithCallback onSuccess");
                        })
                        .addOnFailureListener(e -> {
                            LogUtil.e(TAG, "requestLocationUpdatesWithCallback onFailure:" + e.getMessage());
                        });
            }).addOnFailureListener(e -> {
                LogUtil.e(TAG, "checkLocationSetting onFailure:" + e.getMessage());
                if (locationListener!=null){
                    locationListener.onProviderDisabled(null);
                }
            });

            int notificationId = 1;
            enableBackgroundLocation(notificationId, notification);
        } catch (Exception e) {
            LogUtil.e(TAG, "requestLocationUpdatesWithCallback exception:" + e.getMessage());
        }

        //https://developer.huawei.com/consumer/cn/doc/HMSCore-Guides/location-develop-steps-0000001050746143#section1782164194913
        try {
            Task<Location> lastLocation = mFusedLocationProviderClient.getLastLocation();
            lastLocation.addOnSuccessListener(location -> {
                if (location == null) {
                    LogUtil.i(TAG, "getLastLocation onSuccess location is null");
                    return;
                }
                LogUtil.i(TAG, "getLastLocation onSuccess location[Longitude,Latitude]:" + location.getLongitude() + "," + location.getLatitude());
                if (locationListener != null) {
                    locationListener.onLocationChanged(location, true);
                }
            }).addOnFailureListener(e -> LogUtil.e(TAG, "getLastLocation onFailure:" + e.getMessage()));
        } catch (Exception e) {
            LogUtil.e(TAG, "getLastLocation exception:" + e.getMessage());
        }
    }

    public void enableBackgroundLocation(int notificationId, @Nullable Notification notification) {
        if (mFusedLocationProviderClient != null && notification != null) {
            mFusedLocationProviderClient.enableBackgroundLocation(notificationId, notification);
        }
    }


    public void stopLocation() {
        try {
            if (mFusedLocationProviderClient == null || hmsLocationCallback == null) return;
            try {
                mFusedLocationProviderClient.disableBackgroundLocation();
            } catch (Exception e) {
                e.printStackTrace();
            }
            Task<Void> voidTask = mFusedLocationProviderClient.removeLocationUpdates(hmsLocationCallback);
            voidTask.addOnSuccessListener(new OnSuccessListener<Void>() {
                @Override
                public void onSuccess(Void aVoid) {
                    LogUtil.i(TAG, "removeLocationUpdatesWithCallback onSuccess");
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(Exception e) {
                    LogUtil.e(TAG, "removeLocationUpdatesWithCallback onFailure:" + e.getMessage());
                }
            });
        } catch (Exception e) {
            LogUtil.e(TAG, "removeLocationUpdatesWithCallback exception:" + e.getMessage());
            e.printStackTrace();
        }
    }


    //[华为定位回调监听]
    public class HMSLocationCallback extends LocationCallback {
        @Override
        public void onLocationResult(LocationResult locationResult) {
//            LogUtil.e(TAG, "isHuawei onLocationResult:" + (locationResult == null ? null : locationResult.toString()));
            if (locationResult == null) return;
            List<Location> locations = locationResult.getLocations();
            if (!locations.isEmpty() && locationListener != null) {
                for (Location location : locations) {
                    locationListener.onLocationChanged(location);
                }
            }
        }

        @Override
        public void onLocationAvailability(LocationAvailability locationAvailability) {
            LogUtil.e(TAG, "isHuawei onLocationAvailability:" + (locationAvailability == null ? null : locationAvailability.isLocationAvailable()));
            if (locationListener == null || locationAvailability == null) return;
            // [当前定位是否可用]
            if (locationAvailability.isLocationAvailable()) {
                locationListener.onProviderEnabled(null);
            } else {
                locationListener.onProviderDisabled(null);
            }
        }
    }


    private volatile static HWLocationInstance instance;

    public static HWLocationInstance getInstance() {
        if (instance == null) {
            synchronized (HWLocationInstance.class) {
                if (instance == null) {
                    instance = new HWLocationInstance();
                }
            }
        }
        return instance;
    }

}
